home *** CD-ROM | disk | FTP | other *** search
- /**
- *
- * Name pcshrink -- Release all memory not needed but allocated
- * by DOS when the program is loaded.
- *
- * Synopsis ercode = pcshrink(psize);
- * int ercode Return code from DOS function call
- * unsigned *psize Memory size of the program in paragraphs
- * after unused memory is released.
- *
- * Description When DOS loads a program, all available memory is
- * allocated to it. PCSHRINK releases the memory beyond the
- * program memory returning it to the free memory pool.
- * The memory block is altered by making a call to PCSETBLK;
- * the segment address of the block is given by the program
- * segment prefix. The adjusted size is the code size plus
- * the data size. For large data memory models, there may
- * no available memory if the stack and heap use all available
- * memory.
- *
- * Returns ercode Error code returned from the call to
- * PCSETBLK.
- * psize Size of the memory block allocated to
- * program in paragraphs.
- *
- * Version 1.1 (C)Copyright Blaise Computing Inc. 1983, 1984
- *
- **/
- #include <compiler.h>
-
- #define min(a,b) ((a)<=(b)?(a):(b))
-
- struct segads /* Offset, segment address type */
- {
- unsigned r;
- unsigned s;
- };
- #define ADS struct segads /* Abbreviation */
-
- #if LAT200
- extern ADS _psp; /* Program segment prefix */
- extern unsigned _top; /* Top of stack relative to SS */
- #endif
- #if CI201A
- extern ADS _pspseg;
- #endif
- #if LAT104
- extern unsigned _pgmseg;
- extern unsigned _top; /* Number of bytes in data seg */
- #endif
- #if CI133D
- extern unsigned _pgmseg;
- #endif
-
- int pcshrink(psize)
- unsigned *psize;
- {
-
- unsigned code_size,data_size;
- unsigned size; /* Request size of prog block */
- unsigned cs,ss,ds,es; /* Segment register values */
- ADS ptopmem,topmem_ads;
- unsigned topmem; /* Top of memory */
- #if CI201A & LDATA
- unsigned long ptrtoabs();
- #endif
- unsigned seg;
- int utslmove();
-
- #if LAT104 | CI133D
- ptopmem.s = _pgmseg; /* Top of memory size is at */
- #endif /* offset 2 of the program */
- #if LAT200 /* segment prefix. */
- ptopmem.s = _psp.s;
- #endif
- #if CI201A
- ptopmem.s = _pspseg.s;
- #endif
- ptopmem.r = 2;
- #if LDATA
- #if CI201A
- topmem_ads.s = (unsigned)((ptrtoabs(&topmem) & 0xffff0L) >> 4L);
- topmem_ads.r = (unsigned)(ptrtoabs(&topmem) & 0xfL);
- #else
- topmem_ads.s = (unsigned)(((long)(&topmem) & 0xffff0L) >> 4L);
- topmem_ads.r = (unsigned)((long)(&topmem) & 0xfL);
- #endif
- #else
- utsreg(&cs,&ss,&ds,&es); /* Return segment reg values */
- topmem_ads.s = ds;
- topmem_ads.r = &topmem;
- #endif
- utslmove(&ptopmem,&topmem_ads,2);
-
- #if LAT104
- code_size = ds - _pgmseg; /* code size is DS - PSP */
- data_size = _top/16 + 1; /* data size in paragraphs */
- size = code_size + data_size;
- return(pcsetblk(_pgmseg,size,psize));
- #endif
-
- #if LAT200
- #if LDATA
- size = topmem - _psp.s;
- *psize = size; /* All of memory is used */
- return(0);
- #else
- code_size = ds - _psp.s; /* code size is DS - PSP */
- data_size = _top/16 + 1; /* data size in paragraphs */
- size = code_size + data_size;
- return(pcsetblk(_psp.s,size,psize));
- #endif
- #endif
-
- #if CI133D
- data_size = min(topmem - ss,0x1000); /* The data size is the min */
- code_size = ds - _pgmseg; /* of 0x1000 (64K) and the */
- size = data_size + code_size; /* data segment size. */
- return(pcsetblk(_pgmseg,size,psize));
- #endif
-
- #if CI201A
- /* The C86 Optimizing compiler frees up all available memory at */
- /* initiation, so pcsetblk need not be called. To return the size */
- /* of the program, we compute how much free memory is left and */
- /* subtract that from the difference of top of memory and the Pro- */
- /* gram Segment Prefix. */
-
- pcalloc(0xffff,&seg,psize);
- *psize = (topmem - _pspseg.s) - *psize;
- return(0);
- #endif
-
- }